package com.maodou.core.manager

import com.maodou.core.datastore.DataStore
import com.maodou.core.model.DictionaryData
import com.maodou.core.model.UserInfo
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import javax.inject.Inject
import javax.inject.Singleton

/**
 * 全局状态管理器
 * 负责管理应用级别的状态，包括：
 * - 登录状态
 * - 用户信息
 * - 后台字典数据
 * - 应用配置等
 */
@Singleton
class GlobalStateManager @Inject constructor(
    private val dataStore: DataStore
) {
    
    companion object {
        private const val KEY_USE_AGREEMENT = "app_use_agreement"
        private const val KEY_USER_INFO = "user_info"
        private const val KEY_LOGIN_TOKEN = "login_token"
        private const val KEY_IS_LOGGED_IN = "is_logged_in"
        private const val KEY_DICTIONARY_DATA = "dictionary_data"
        private const val KEY_APP_CONFIG = "app_config"
    }
    
    // app使用协议
    private val _isAgree = MutableStateFlow(false)
    val isAgree: StateFlow<Boolean> = _isAgree.asStateFlow()

    // 登录状态
    private val _isLoggedIn = MutableStateFlow(false)
    val isLoggedIn: StateFlow<Boolean> = _isLoggedIn.asStateFlow()
    
    // 用户信息
    private val _userInfo = MutableStateFlow<UserInfo?>(null)
    val userInfo: StateFlow<UserInfo?> = _userInfo.asStateFlow()
    
    // 登录Token
    private val _loginToken = MutableStateFlow<String?>(null)
    val loginToken: StateFlow<String?> = _loginToken.asStateFlow()
    
    // 字典数据
    private val _dictionaryData = MutableStateFlow<Map<String, List<DictionaryData>>>(emptyMap())
    val dictionaryData: StateFlow<Map<String, List<DictionaryData>>> = _dictionaryData.asStateFlow()
    
    // 应用配置
    private val _appConfig = MutableStateFlow<Map<String, Any>>(emptyMap())
    val appConfig: StateFlow<Map<String, Any>> = _appConfig.asStateFlow()
    
    /**
     * 初始化状态管理器
     * 从本地存储加载已保存的状态
     */
    suspend fun initialize() {
        // 加载app使用协议同意情况
        _isAgree.value = dataStore.keyValue.getBoolean(KEY_USE_AGREEMENT, false)

        // 加载登录状态
        _isLoggedIn.value = dataStore.keyValue.getBoolean(KEY_IS_LOGGED_IN, false)
        
        // 加载用户信息
        _userInfo.value = dataStore.keyValue.getObject(KEY_USER_INFO, UserInfo::class.java)
        
        // 加载登录Token
        _loginToken.value = dataStore.keyValue.getString(KEY_LOGIN_TOKEN)
        
        // 加载字典数据
        val savedDictionary = dataStore.keyValue.getObject(KEY_DICTIONARY_DATA, Map::class.java) as? Map<String, List<DictionaryData>>
        _dictionaryData.value = savedDictionary ?: emptyMap()
        
        // 加载应用配置
        val savedConfig = dataStore.keyValue.getObject(KEY_APP_CONFIG, Map::class.java) as? Map<String, Any>
        _appConfig.value = savedConfig ?: emptyMap()
    }
    
    // ==================== 登录相关 ====================
    
    /**
     * 设置登录状态
     */
    suspend fun setLoginState(isLoggedIn: Boolean, token: String? = null, user: UserInfo? = null) {
        _isLoggedIn.value = isLoggedIn
        _loginToken.value = token
        _userInfo.value = user
        
        // 持久化到本地
        dataStore.keyValue.putBoolean(KEY_IS_LOGGED_IN, isLoggedIn)
        if (token != null) {
            dataStore.keyValue.putString(KEY_LOGIN_TOKEN, token)
        } else {
            dataStore.keyValue.remove(KEY_LOGIN_TOKEN)
        }
        if (user != null) {
            dataStore.keyValue.putObject(KEY_USER_INFO, user,UserInfo::class.java)
        } else {
            dataStore.keyValue.remove(KEY_USER_INFO)
        }
    }
    
    /**
     * 登录
     */
    suspend fun login(token: String, user: UserInfo) {
        setLoginState(true, token, user)
    }
    
    /**
     * 登出
     */
    suspend fun logout() {
        setLoginState(false, null, null)
        // 清除其他相关数据
        clearUserRelatedData()
    }
    
    /**
     * 更新用户信息
     */
    suspend fun updateUserInfo(user: UserInfo) {
        _userInfo.value = user
        dataStore.keyValue.putObject(KEY_USER_INFO, user,UserInfo::class.java)
    }

    /**
     * app使用协议
     */
    suspend fun setAgreementState(isAgree: Boolean) {
        _isAgree.value = isAgree
        dataStore.keyValue.putBoolean(KEY_USE_AGREEMENT,isAgree)
    }
    
    /**
     * 更新登录Token
     */
    suspend fun updateToken(token: String) {
        _loginToken.value = token
        dataStore.keyValue.putString(KEY_LOGIN_TOKEN, token)
    }
    
    /**
     * 检查是否需要重新登录
     */
    fun needReLogin(): Boolean {
        return !_isLoggedIn.value || _loginToken.value.isNullOrEmpty()
    }
    
    // ==================== 字典数据相关 ====================
    
    /**
     * 更新字典数据
     */
    suspend fun updateDictionaryData(data: Map<String, List<DictionaryData>>) {
        _dictionaryData.value = data
        dataStore.keyValue.putObject(KEY_DICTIONARY_DATA, data, Map::class.java)
    }
    
    /**
     * 获取指定类型的字典数据
     */
    fun getDictionaryByType(type: String): List<DictionaryData> {
        return _dictionaryData.value[type] ?: emptyList()
    }
    
    /**
     * 添加或更新单个字典类型的数据
     */
    suspend fun updateDictionaryByType(type: String, data: List<DictionaryData>) {
        val currentData = _dictionaryData.value.toMutableMap()
        currentData[type] = data
        updateDictionaryData(currentData)
    }
    
    /**
     * 获取字典项的显示名称
     */
    fun getDictionaryDisplayName(type: String, code: String): String? {
        return getDictionaryByType(type).find { it.code == code }?.name
    }
    
    // ==================== 应用配置相关 ====================
    
    /**
     * 更新应用配置
     */
    suspend fun updateAppConfig(config: Map<String, Any>) {
        _appConfig.value = config
        dataStore.keyValue.putObject(KEY_APP_CONFIG, config, Map::class.java)
    }
    
    /**
     * 获取配置项
     */
    fun getConfigValue(key: String): Any? {
        return _appConfig.value[key]
    }
    
    /**
     * 设置单个配置项
     */
    suspend fun setConfigValue(key: String, value: Any) {
        val currentConfig = _appConfig.value.toMutableMap()
        currentConfig[key] = value
        updateAppConfig(currentConfig)
    }
    
    /**
     * 获取字符串配置
     */
    fun getStringConfig(key: String, defaultValue: String = ""): String {
        return getConfigValue(key) as? String ?: defaultValue
    }
    
    /**
     * 获取布尔配置
     */
    fun getBooleanConfig(key: String, defaultValue: Boolean = false): Boolean {
        return getConfigValue(key) as? Boolean ?: defaultValue
    }
    
    /**
     * 获取整数配置
     */
    fun getIntConfig(key: String, defaultValue: Int = 0): Int {
        return getConfigValue(key) as? Int ?: defaultValue
    }
    
    // ==================== 便捷方法 ====================
    
    /**
     * 获取当前用户ID
     */
    fun getCurrentUserId(): String? {
        return _userInfo.value?.id
    }
    
    /**
     * 获取当前用户名
     */
    fun getCurrentUserName(): String? {
        return _userInfo.value?.nickName
    }
    
    /**
     * 检查用户是否有指定权限
     */
    fun hasPermission(permission: String): Boolean {
        return _userInfo.value?.permissions?.contains(permission) == true
    }
    
    /**
     * 获取用户角色
     */
    fun getUserRole(): String? {
        return _userInfo.value?.role
    }
    
    /**
     * 清除用户相关数据
     */
    private suspend fun clearUserRelatedData() {
        // 可以在这里清除一些用户相关的缓存数据
        // 例如：用户偏好设置、临时数据等
    }
    
    // ==================== Flow 扩展 ====================
    
    /**
     * 监听登录状态变化
     */
    fun observeLoginState(): Flow<Boolean> = isLoggedIn
    
    /**
     * 监听用户信息变化
     */
    fun observeUserInfo(): Flow<UserInfo?> = userInfo
    
    /**
     * 监听指定类型的字典数据变化
     */
    fun observeDictionaryByType(type: String): Flow<List<DictionaryData>> {
        return dictionaryData.map { it[type] ?: emptyList() }
    }
    
    /**
     * 监听指定配置项变化
     */
    fun observeConfigValue(key: String): Flow<Any?> {
        return appConfig.map { it[key] }
    }

    fun forceLogout() {
        GlobalScope.launch(kotlinx.coroutines.Dispatchers.IO) {
            try {
                logout()
            } catch (_: Throwable) {
                // 忽略异常
            }
        }
    }
}